package com.xmu.edu.tisp.synchronous;

//business class for Synchronous
//By Chenbo 2011-08-06

import java.util.List;

import org.jdom.Document;
import org.jdom.Element;

import android.content.ContentValues;

import com.xmu.edu.tisp.database.BaseService;
import com.xmu.edu.tisp.database.DbService;
import com.xmu.edu.tisp.database.Tables;
import com.xmu.edu.tisp.webservice.ServiceXmlMaker;
import com.xmu.edu.tisp.webservice.ServiceXmlParser;
import com.xmu.edu.tisp.webservice.ServiceXmlResult;
import com.xmu.edu.tisp.webservice.WebServices;

public class SynchronousAction {

	public static final String SYNC_KEY = "DATA_STATE";
	public static final String[] downloadMethods = { "GetTobaccoCommonData",
			"GetContractCommonData", "GetTaskCommonData",
			"GetPreCheckCommonData" };
	public static final String[] uploadMethods = { "SendContractOprData",
			"SendTaskFeedBackData", "SendPreCheckOprData" };

	public static void storeMasters(ServiceXmlParser parser) {
		int k = parser.getMasterCount();
		for (int i = 0; i < k; ++i) {
			String tableName = parser.getMasterAttributes(i)
					.getAsString("type");
			List<ContentValues> values = parser.getArrays(i);
			DbService service = BaseService.createService(tableName);
			for (ContentValues item : values) {
				System.out.println("master " + item);
				insertUpdateOrDelete(service, tableName, item);
			}
		}
	}

	public static void storeDetails(ServiceXmlParser parser) {
		int k = parser.getDetailCount();
		for (int i = 0; i < k; ++i) {
			String tableName = parser.getDetailAttributes(i)
					.getAsString("type");
			List<ContentValues> values = parser.getDetailArrays(i);
			DbService service = BaseService.createService(tableName);
			for (ContentValues item : values) {
				System.out.println("detail " + item);
				insertUpdateOrDelete(service, tableName, item);
			}
		}
	}

	public static boolean download(String method) throws Exception {
		String result = WebServices.invokeService(method, null, null);
		if (result == null)
			return false;
		ServiceXmlParser parser = new ServiceXmlParser(result);
		if (parser.isOK()) {
			storeMasters(parser);
			storeDetails(parser);
			parser = null;
			return true;
		}
		return false;
	}

	private static void insertUpdateOrDelete(DbService service,
			String tableName, ContentValues cv) {
		if (tableName.toUpperCase().equals("XJSZXX"))
			service.dealXJSZXX(cv);
		else {
			if (cv.containsKey(SYNC_KEY)) {
				String state = cv.getAsString(SYNC_KEY).trim();
				if (state.equals("1")) {

					service.delete(cv.getAsString(Tables.primaryKey(tableName)));
				} else {
					cv.remove(SYNC_KEY);
					service.insertOrUpdate(cv);
				}
			} else {
				service.insertOrUpdate(cv);
			}
		}
	}

	public static boolean downloadAll() throws Exception {
		int i = 0;
		for (String method : downloadMethods) {
			if (download(method)) {
				++i;
			}
		}
		return i > 0;
	}

	public static boolean downloadTobaccoCommonData() throws Exception {

		return download("GetTobaccoCommonData");
	}

	public static boolean downloadContractCommonData() throws Exception {
		return download("GetContractCommonData");
	}

	public static boolean downloadTaskCommonData() throws Exception {
		return download("GetTaskCommonData");
	}

	public static boolean downloadPreCheckCommonData() throws Exception {
		return download("GetPreCheckCommonData");
	}

	public static void setAllUploaded(String[] tables) {
		String time = Utils.getCurrentTime();
		for (String table : tables) {
			BaseService.getdb().execSQL(
					"update " + table + " set DT_SYNC_FLAG=1,DT_SYNC_TIME='"
							+ time + "'");
		}
	}

	public static void setUploadedById(String tableName, String pk, String id) {
		ContentValues values = new ContentValues();
		values.put("DT_SYNC_TIME", Utils.getCurrentTime());
		values.put("DT_SYNC_FLAG", "1");
		BaseService.getdb().update(tableName, values, pk + "=?",
				new String[] { id });
	}

	public static void setUploaded(String tableName, List<String> ids) {
		String pk = Tables.primaryKey(tableName);
		for (String id : ids) {
			setUploadedById(tableName, pk, id);
		}
		/*
		 * String time=Utils.getCurrentTime();
		 * 
		 * String
		 * sql="update "+tableName+" set DT_SYNC_FLAG=1,DT_SYNC_TIME='"+time
		 * +"' where "+pk+" in ("+Utils.join(ids,",")+")";
		 * BaseService.getdb().execSQL(sql);
		 */

		System.out.println("update.." + tableName + " " + ids.size()
				+ " item(s)");
	}

	// read database tables and make xml
	public static String makeXml(String rootTag, String[] masters) {
		Element root = new Element(rootTag);
		root.setAttribute("TECHNICIAN_ID", Utils.getTabaccoTechID());
		Document doc = new Document(root);
		for (String master : masters) {
			root.addContent(ServiceXmlMaker.createMasterElement(master, master
					+ "_DETAIL"));
		}
		return ServiceXmlMaker.xmlAsString(doc);
	}

	// deal with the xml returned from update..service
	public static boolean afterUpload(String[] tables, String result) {
		if (result == null)
			return false;
		ServiceXmlResult parser = new ServiceXmlResult(result);
		if (parser.isOK()) {
			if (parser.isSuccess()) {
				setAllUploaded(tables);
			} else {
				List<String> retMasters = parser.getMasters();
				for (String retMaster : retMasters) {
					List<String> ids = parser.getUpdateIds(retMaster);
					for (String table : tables) {
						if (table.equalsIgnoreCase(retMaster)) {
							setUploaded(retMaster, ids);
							break;
						}
					}
				}
			}
			return true;
		}
		return false;
	}

	public static boolean upload(String method, String rootTag, String[] masters) throws Exception {
		String xml = makeXml(rootTag, masters);
		if (xml == null)
			return false;
		System.out.println(xml);
		String result = WebServices.upload(method, xml);
		// System.out.println("service result:");
		System.out.println(result);
		return afterUpload(masters, result);
	}

	public static boolean uploadContractOprData() throws Exception {
		return upload(uploadMethods[0], "ContractOprData", new String[] {
				"XJSZ_ZYMD", "XJSZ_ZYSQQR" });
	}

	public static boolean uploadTaskFeedBackData() throws Exception {
		return upload(uploadMethods[1], "TaskFeedBackData",
				new String[] { "CR_TASK_FEEDBACK"
				// ,"XJSZ_ZYMD",
				// "XJSZ_ZYSQQR",
				});
	}

	public static boolean uploadPreCheckOprData() throws Exception {
		return upload(uploadMethods[2], "PreCheckOprData",
				new String[] { "BU_PRE_CHECK" });
	}

}
